﻿using Mono.Cecil;
using Mono.Cecil.Cil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CecilTestWriter1
{//D:\testDLLS\CecilTestdll1.dll
    class Program
    {
        static String assemblyReadPath = @"D:\testDLLS\CecilTestdll1.dll";
        static String assemblyInjectCode = @"D:\testDLLS\CecilInjectLib.dll";
        static String assemblyWritePath = @"D:\testDLLS\CecilModifiedOut1.dll";
        static void Main()
        {
            var typeName = "Class1";
            var methodName = "test1";

            var assembly = AssemblyDefinition.ReadAssembly(assemblyReadPath);
            assembly.Name.Name += ".Patched";

            var injassembly = AssemblyDefinition.ReadAssembly(assemblyInjectCode);


            var typedefinj = injassembly.MainModule.Types.Single(t => t.Name == "Class2");
            var injmethDefinition = typedefinj.Methods.Single(t => t.Name == "test2");

            var typeDefinition = assembly.MainModule.Types.Single(t => t.Name == typeName);
            var methDefinition = typeDefinition.Methods.Single(t => t.Name == methodName);

            var setMethodWriter = methDefinition.Body.GetILProcessor();

            var firstExistingInstruction = setMethodWriter.Body.Instructions[0];
            setMethodWriter.InsertBefore(firstExistingInstruction, setMethodWriter.Create(OpCodes.Call, assembly.MainModule.Import(injmethDefinition.Resolve())));
            //setMethodWriter.Replace(firstExistingInstruction, setMethodWriter.Create(OpCodes.Call, assembly.MainModule.Import(injmethDefinition.Resolve())));
            assembly.Write(assemblyReadPath.Replace(".dll", ".Patched.dll"));
        }
    }
}
